package resources 
{
	import app.textures.TextureInfo;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Graphics;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.HTTPStatusEvent;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import flash.text.TextField;
	import gui.LoaderIndicator;
	import gui.PositionInfo;
	import utils.ErrorsCollector;
	/**
	 * ...
	 * @author Dmitriy Gaiduk
	 */
	public class TextureLoader 
	{
		private var _loader:Loader;
		private var _textureInfo:TextureInfo;
		private static const TEXTURE_PREVIEW:int = 0;
		private static const TEXTURE:int = 1;
		private var _currentLoad:int = - 1;
		private var _preloaderIndicator:LoaderIndicator;
		private var _imageHolder:Sprite;
		private var _frameWidth:Number;
		private var _frameHeight:Number;
		private var _loadSource:Boolean;
		
		/**
		 * 
		 * @param	textureInfo
		 * @param	frameW
		 * @param	frameH
		 * @param	loadSource If need to load source in TextureInfo.sourceURL
		 */
		public function TextureLoader(textureInfo:TextureInfo, frameW:Number, frameH:Number, 
									loadSource:Boolean) 
		{
			_loadSource = loadSource;
			_textureInfo = textureInfo;
			_currentLoad = TextureLoader.TEXTURE_PREVIEW;
			_imageHolder = new Sprite();
			_frameWidth = frameW;
			_frameHeight = frameH;
			drawRect(_imageHolder.graphics, frameW, frameH);
		}
		
		private function drawRect(gr:Graphics, frameW:Number, frameH:Number):void
		{
			gr.lineStyle(1, 0xCCCCCC);
			gr.drawRect(0, 0, frameW, frameH);	
		}
		
		public function run():DisplayObject
		{
			_loader = null;
			switch(_currentLoad)
			{
				case TEXTURE_PREVIEW:
						_loader = new Loader();
						_imageHolder.addChild(_loader);
						_loader.addEventListener(Event.ADDED_TO_STAGE, handleLoaderAddedToStage);
						configureListeners(_loader.contentLoaderInfo);
						// add preloader movie
						_textureInfo.texturePreview = _imageHolder;
						_preloaderIndicator = new LoaderIndicator();
						var pos:PositionInfo = new PositionInfo();
						pos.align = PositionInfo.ALIGN_CENTR_X;
						pos.addAlign(PositionInfo.ALIGN_CENTR_Y);
						_preloaderIndicator.x = pos.getPosX(_frameWidth, _preloaderIndicator.radius * 2);
						_preloaderIndicator.y = pos.getPosY(_frameHeight, _preloaderIndicator.radius * 2);
						_imageHolder.addChild(_preloaderIndicator);
						
					break;
				case TEXTURE:
						
						_loader = new Loader(); 
						configureListeners(_loader.contentLoaderInfo);
						try
						{
							_loader.load(new URLRequest(_textureInfo.sourceURL)); 
						}
						catch(er:Error)
						{
							handleError(er.message);
							return null;
						}
					break;
			}
			
			return _imageHolder;
		}
		
		private function handleLoaderAddedToStage(e:Event):void 
		{
			_loader.removeEventListener(Event.ADDED_TO_STAGE, handleLoaderAddedToStage);
			try
			{
				_textureInfo.texturePreview = _loader;
				_loader.load(new URLRequest(_textureInfo.previewURL)); 
			}
			catch(er:Error)
			{
				handleError(er.message);
				return ;
			}
		}
		
		
		
		private function handleError(err:String):void
		{
			trace(this + " error: " + err);
			ErrorsCollector.collectError("Texture loader Loader: " + err);
		}
		
		// добавляет обработчики событий
		private function configureListeners(dispatcher:IEventDispatcher):void 
		{
            dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
            dispatcher.addEventListener(Event.COMPLETE, handleLoadComplete);
			dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			
           /* dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
            dispatcher.addEventListener(Event.INIT, initHandler);
            dispatcher.addEventListener(Event.OPEN, openHandler);
            dispatcher.addEventListener(Event.UNLOAD, unLoadHandler);*/
        }
		
		// удаляет обработчики событий
		private function removeListeners(dispatcher:IEventDispatcher):void
		{
			dispatcher.removeEventListener(Event.COMPLETE, handleLoadComplete);
			dispatcher.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			dispatcher.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
		}
		
		private function handleLoadComplete(e:Event):void 
		{
			removeListeners(_loader.contentLoaderInfo);
			switch(_currentLoad)
			{
				case TEXTURE_PREVIEW:
						_imageHolder.addChild(_loader.content);
						if (_loadSource)
						{
							if (_preloaderIndicator != null)
							{
								if (_preloaderIndicator.parent != null)
								{
									var par:DisplayObjectContainer = _preloaderIndicator.parent;
									_preloaderIndicator.parent.removeChild(_preloaderIndicator);
									par.addChild(_preloaderIndicator);
								}
							}
							_currentLoad = TEXTURE;
							run();
						}else
						{
							if (_preloaderIndicator != null)
							{
								if (_preloaderIndicator.parent != null)
								{
									_preloaderIndicator.parent.removeChild(_preloaderIndicator);
								}
							}
							_preloaderIndicator = null;
							destroy();
						}
					break;
				case TEXTURE:
						var bitmapData:BitmapData = new BitmapData(_loader.width, _loader.height, false, 0xFFFFFF);
						bitmapData.draw(_loader, null, null, null, null, true);
						_textureInfo.texture = bitmapData;
						if (_preloaderIndicator != null)
						{
							if (_preloaderIndicator.parent != null)
							{
								_preloaderIndicator.parent.removeChild(_preloaderIndicator);
							}
						}
						_preloaderIndicator = null;
						destroy();
					break;
			}
		}
		
		
		private function httpStatusHandler(event:HTTPStatusEvent):void 
		{
            //handleError("httpStatusHandler: " + event);
        }

        private function initHandler(event:Event):void 
		{
            //handleError("initHandler: " + event);
        }

        private function ioErrorHandler(event:IOErrorEvent):void 
		{
			//ошибка загрузки
            handleError("Load image error: " + event.text + " url: " + _textureInfo.sourceURL);
        }

        private function openHandler(event:Event):void 
		{
            //trace("openHandler: " + event);
        }

        private function progressHandler(event:ProgressEvent):void 
		{
			if (_preloaderIndicator != null)
			{
				if (event.bytesTotal != 0)
				{
					_preloaderIndicator.setPercent(event.bytesLoaded / event.bytesTotal * 100);
				}
			}
            //trace("progressHandler: bytesLoaded=" + event.bytesLoaded + " bytesTotal=" + event.bytesTotal);
        }

        private function unLoadHandler(event:Event):void 
		{
            //trace("unLoadHandler: " + event);
        }
		
		public function destroy():void
		{
			_preloaderIndicator = null;
			_textureInfo = null;
			_loader = null;
		}
		
	}

}